<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <script>
        //统计字符串中“aaaabbbcccddfgh”中字母个数或者最多字母数 
        //reduce用法
        var fa = [1, 2, 3, 4]

        function red(a, b) {
            console.log(arguments);
            return a + b;
        }
        fa.reduce(red);
        //Arguments(4) [1, 2, 1, Array(4), callee: ƒ, Symbol(Symbol.iterator): ƒ]  //a=1,b=2    
        //Arguments(4) [3, 3, 2, Array(4), callee: ƒ, Symbol(Symbol.iterator): ƒ]  //a=3,b=3
        //Arguments(4) [6, 4, 3, Array(4), callee: ƒ, Symbol(Symbol.iterator): ƒ]  //a=6,b=4
        //语法  arr.reduce(callback,[initialValue])   
        //      arr.reduce(function(total,currentValue,currentIndex,arr),initialValue)
        //总结  遍历数组元素，从头开始，依次往下，第一个参数是上一次的返回值，第二个参数是下一个数组元素，首次的时候第一个和第二个参数分别是 array[0],  array[1] 
        const scores = [{
                subject: 'math',
                score: 88
            },
            {
                subject: 'chinese',
                score: 95
            },
            {
                subject: 'english',
                score: 80
            }
        ];
        const dis = {
            math: 0.5,
            chinese: 0.3,
            english: 0.2
        }
        const sum = scores.reduce((pre, item) => {
            return pre + item.score * dis[item.subject]
        }, 0)
        console.log(sum) // 88.5
        // 0+88*0.5=44    pre=0,item={subject:"chinese",score:95}
        // 44+95*0.3=72.5   pre=44,item={subject:"english",score:80}
        // 72.5+80*0.2=88.5 pre=72.5,item={subject:"chinese",score:95}
        var numbers = [65, 44, 12, 4];
        function getSum(total, num) {
            //  total   num
            //   65     44
            //   109    12
            //   121     4
            //   125
            return total + num; //65+44+12+4 
        }

        function myFunction(item) {
            var result = numbers.reduce(getSum);
            console.log(result);
        }
        myFunction();
        //es6中的reduce写法  
        let arr = 'aaaabbbcccddfgh';
        let info = arr.split('').reduce((p, k) => (p[k]++ || (p[k] = 1), p), {});
        console.log(info); //{ a: 4, b: 3, c: 3, d: 2,f:1,g:1,h:1 }
        //取出字母最多的个数字母
        function num(str) {
            var a = {};
            var b = str.split("");
            // key为元素   值为个数
            for (let i = 0; i < b.length; i++) {
                if (a[b[i]]) {
                    a[b[i]]++;
                } else {
                    a[b[i]] = 1;
                }
            }
            // 通过比较找出最大的
            var maxLetter = "";
            var levelNum = 0;
            for (const k in a) {
                if (a[k] > levelNum) {
                    levelNum = a[k];
                    maxLetter = k;
                }
            }
            console.log(maxLetter + ":" + levelNum);
            return maxLetter;
        }
        var cc = "aaaabbbcccddfgh";
        num(cc); //a:4
        //思路1
            // 创建一个目标结果对象（即最后函数返回值，代码中为 result）；
            // 循环遍历字符串（传入的参数, str），结果对象（result）里存在该字母，则次数＋1
            // 若不存在，则以 {当前字母: 1} 的形式加到结果对象中。
        function getMost(str) {
            // 步骤1
            var result = {};
            for (let i in str) {
                if (str[i] in result) {
                    // 步骤2
                    result[str[i]]++;
                } else {
                    // 步骤3
                    var object = {};
                    object[str[i]] = 1;
                    result = Object.assign(result, object);
                }
            }
            return result;
        }
        var result = getMost("aaaabbbcccddfgh");
        console.log(result); //{ a: 4, b: 3, c: 3, d: 2,f:1,g:1,h:1}
        //getMost方法es6写法  
        function getMost(str) {
            var result = Array.prototype.reduce.call(str, function (allWords, curWord) {
                allWords[curWord] ? allWords[curWord]++ : allWords[curWord] = 1;
                return allWords;
            }, {});

            return result;
        }
        var result = getMost("aaaabbbcccddfgh");
        console.log(result); //{ a: 4, b: 3, c: 3, d: 2,f:1,g:1,h:1}
        //思路2
        //例：原字符串 “xyzzyxyz”
        // 使用 split()，将字符串转换为字符串数组：['x','y','z','z','y','x','y','z']；
        // 使用 sort()，将乱序的字符串数组排序：['x','x','y','y','y','z','z','z']；
        // 使用 join()，将数组组合为字符串：'xxyyyzzz'；
        // 使用 match()，将字符串通过正则，把连续重复字母，分组返回：['xx'],['yyy'],['zzz']；
        // 使用 reduce，对数组进行迭代，在回调函数里生成结果函数：{x: 2, y: 3, z: 3}
        function getMost(str) {
            var result = {};
            result = str.split('').sort().join('').match(/(.)\1+/g).reduce(function (result, cur) {
                result[cur[0]] = cur.length;
                return result;
            }, {});

            return result;
        }
        var result = getMost("xyzzyxyz");
        console.log(result); //{x: 2, y: 3, z: 3}

        function distinction(str) {
            var obj = {};
            return (function (){
             for (var i = 0; i < str.length; i++) {
                    var v = str.charAt(i);
                    if (obj[v] && obj[v].value == v) {
                        obj[v].count = ++obj[v].count;
                    } else {
                        obj[v] = {};
                        obj[v].count = 1;
                        obj[v].value = v;
                    }
                }
                return obj
            })()
        }
        var str = 'aaabbbbbddddddd';
        console.log(distinction(str));
        //a:{count:3,value:"a"};
        //b:{count:5,value:"b"};
        //c:{count:7,value:"c"};
    </script>
</body>

</html>